// Copyright(c) 2011 Matthew McMullan, Jorel Lalicki and Mike Heise, Jorel Lalicki and Mike Heise. See copying.txt for details.

#ifndef __agml_invsqrt_h__
#define __agml_invsqrt_h__

// make sure that this file is never included directly
#ifndef __agml_agml_h__
#error "Include AGML from agml.h only. This file is not a valid entry point for the library."
#endif

namespace agml {
/* fixme: wtf?
mstatic<f32,4,4> invsqrt(const mstatic<f32,4,4>&o){
	mstatic<f32,4,4> dest;
	dest.simd[0] = _mm_rsqrt_ps(o.simd[0]);
	dest.simd[1] = _mm_rsqrt_ps(o.simd[1]);
	dest.simd[2] = _mm_rsqrt_ps(o.simd[2]);
	dest.simd[3] = _mm_rsqrt_ps(o.simd[3]);
	return dest;
}
*/
f32 invsqrt(f32 fl){
	_v128 temp = _mm_set1_ps(fl);
    f32 tmp;
	_mm_store_ss(&tmp, _mm_rsqrt_ps(temp));
    return tmp;
}

_v128 invsqrt(const _v128 &o){
	return _mm_rsqrt_ps(o);
}

//actually, we have regular square roots here too. go figure.
/* fixme: wtf?
mstatic<f32,4,4> sqrt(const mstatic<f32,4,4>&o){
	mstatic<f32,4,4> dest;
	dest.simd[0] = _mm_rcp_ps(_mm_rsqrt_ps(o.simd[0]));
	dest.simd[1] = _mm_rcp_ps(_mm_rsqrt_ps(o.simd[1]));
	dest.simd[2] = _mm_rcp_ps(_mm_rsqrt_ps(o.simd[2]));
	dest.simd[3] = _mm_rcp_ps(_mm_rsqrt_ps(o.simd[3]));
	return dest;
}*/

f32 sqrt(f32 fl){
	_v128 temp = _mm_set1_ps(fl);
    f32 ret;
	_mm_store_ss(&ret, _mm_rcp_ps(_mm_rsqrt_ps(temp)));
    return ret;
}

_v128 sqrt(const _v128 &o){
	return _mm_rcp_ps(_mm_rsqrt_ps(o));
}

}

#endif
